package cn.phecda.boot.common.lang.util;

import cn.phecda.boot.common.lang.constants.DefaultConsts;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * <p> Gson工具 </p>
 *
 * @author : wanpinwei
 */
@Slf4j
public final class GsonUtils {
    private static final byte[] lock = new byte[0];
    private static final GsonBuilder GSON_BUILDER = new GsonBuilder();
    private static Gson INSTANCE;

    static {
        GSON_BUILDER.enableComplexMapKeySerialization();
        GSON_BUILDER.serializeNulls();
        GSON_BUILDER.setDateFormat(DefaultConsts.DATE_TIME_PARTTERN);
        GSON_BUILDER.disableHtmlEscaping();
    }

    private static Gson getGson() {
        if (null != INSTANCE) {
            return INSTANCE;
        }

        synchronized (lock) {
            if (null != INSTANCE) {
                return INSTANCE;
            }

            INSTANCE = GSON_BUILDER.create();
        }

        log.info("|Phecda Boot Common|- Lazy creating of Gson");
        return INSTANCE;
    }


    public static JsonElement toJsonElement(String content) {
        return JsonParser.parseString(content);
    }

    public static JsonArray toJsonArray(String content) {
        return toJsonElement(content).getAsJsonArray();
    }

    public static JsonObject toJsonObject(String content) {
        return toJsonElement(content).getAsJsonObject();
    }

    public static <T> String toJson(T domain) {
        return getGson().toJson(domain);
    }

    public static <T> T toBean(String content, Class<T> valueType) {
        return getGson().fromJson(content, valueType);
    }

    public static <T> T toBean(String content, Type typeOfT) {
        return getGson().fromJson(content, typeOfT);
    }

    public static <T> T toList(String content, Class<T> valueType) {
        return getGson().fromJson(content, new TypeToken<List<T>>() {
        }.getType());
    }

    public static <T> List<Map<String, T>> toListMap(String content) {
        return getGson().fromJson(content, new TypeToken<List<Map<String, String>>>() {
        }.getType());
    }

    public static <T> Map<String, T> toMaps(String gsonString) {
        return getGson().fromJson(gsonString, new TypeToken<Map<String, T>>() {
        }.getType());
    }
}
